import { memory_cache } from "utils/decorate/decorate";
import { ABaseEntity } from "./Entitys/BaseEntity";
import { AllEntityTypes, EntityType } from "./Entitys/Entity.interface";

export class EntityDB
{
    // @memory_cache(["entity"])
    /**  @desccipt 所有的实体对象*/
    private _entities:Record<string,ABaseEntity<INoMemory>>={};

 
    protected entities:any={};
    // {room:{type:entity}}
    // @memory_cache(["entity_room"])
    protected _entityTable:Record<string,Record<string,ABaseEntity<INoMemory>[]>>={};
    public init()
    {
        const _this = this;
        const attributefilter = {
            set:(obj:{[key:string]:ABaseEntity<INoMemory>},prop:string,value:ABaseEntity<INoMemory>)=>
            {

                obj[prop] = value;
                if(!_this._entityTable[value.region])
                {
                    _this._entityTable[value.region] = {};
                }
                if(!_this._entityTable[value.region][value.entityType()])
                {
                    _this._entityTable[value.region][value.entityType()] = [];
                }
                // Memory.Debug[`新增实体:${value.GUID}`]
                 global.Log.Info(`新增实体:${value.GUID()}`,value.region,value.entityType());
                _this._entityTable[value.region][value.entityType()].push(value);
                return true;
            },
            deleteProperty:(obj:{[key:string]:ABaseEntity<INoMemory>},prop:string)=>
            {
                const entityguid = prop;
                if(obj[entityguid])
                {
                    const value = obj[entityguid];
                    if( _this._entityTable[value.region][value.entityType()])
                    {
                        const index = _.findIndex(_this._entityTable[value.region][value.entityType()],item=>item.GUID() == entityguid);
                        if(index != -1)
                        {
                            _this._entityTable[value.region][value.entityType()].splice(index,1);
                            if(_this._entityTable[value.region][value.entityType()].length ==0)
                            {
                                delete _this._entityTable[value.region][value.entityType()];
                                if(Object.keys( _this._entityTable[value.region]).length==0)
                                {
                                    delete _this._entityTable[value.region];
                                }
                            }
                        }
                    }
                    global.Log.Info(`删除实体:${value.GUID()}`);
                    delete obj[entityguid];
                
                }
                return true;
            }
        };
        this.entities = new Proxy<{[key:string]:ABaseEntity<INoMemory>}>(this._entities,attributefilter);
    }


    public getEntityByID<T extends ABaseEntity<INoMemory>>(id: string): T 
    {
        if(!this.entities[id])
        {
            global.Log.Warning(`找不到ID所对应实体 :${id}`);
        }
        return this.entities[id]
    }
    public getEntity<T extends EntityType>(type: T, region: string): AllEntityTypes[T] {
        if(!this._entityTable[region] ||!this._entityTable[region][type])
        {
            // global.Log.Warning(`${region} 不存在 或者 ${type} 不存在`);
            return undefined as any
        }
        return this._entityTable[region][type][0] as AllEntityTypes[T];
    }
    public getEntitys<T extends EntityType>(type: T, region: string): AllEntityTypes[T][] {
        if(!this._entityTable[region])
        {
            // this._entityTable[region]={};
            return []
        }
        if(!this._entityTable[region][type])
        {
            return []
            // this._entityTable[region][type]=[];
        }
        return this._entityTable[region][type]  as AllEntityTypes[T][];
    }
    // public getNodeMemory<T extends IEntityMemory>(): T {
    //     throw new Error("Method not implemented.");
    // }
    public add(entity:AllEntityTypes[EntityType])
    {
        this.entities[entity.GUID()]=entity;
    }
    public removeEntityByID(id:string):boolean
    {
        if(this.entities[id]?.onDestory())
        {

            delete this.entities[id];
            // this.deleteEntity(this._entities,id);
            return true;
        }
        return false;
    }
    /**
     * 清理一个区域范围的所有实体 一般指 房间
     * @param region 
     */
    public clear(region:string)
    {
        const entitys = this.Entities[region];
        if(entitys)
        {
            const v = _.flatten( Object.values(entitys));
            for(const e of v)
            {
                this.removeEntityByID(e.GUID());
            }
        }
        delete this.Entities[region];
    }
    public get Entities()
    {
        return this._entityTable
    }

    private deleteEntity(obj:any,entityguid:string)
    {
        if(obj[entityguid])
        {
            const value = obj[entityguid];
            if( this._entityTable[value.region][value.entityType()])
            {
                const index = _.findIndex(this._entityTable[value.region][value.entityType()],item=>item.GUID() == entityguid);
                if(index != -1)
                {
                    this._entityTable[value.region][value.entityType()].splice(index,1);
                }
            }
            delete obj[entityguid];
        }
    }
}